using System;
using System.Runtime.InteropServices;

namespace WindowsAPI
{
    //[Guid("6B3A1F0C-C382-40d6-AA13-33B0AB46EEAA")]
    //public class BatchResultContextMenu : IShellExtInit, IContextMenu
    //{
    //    #region Protected Members
    //    protected const string guid = "{6B3A1F0C-C382-40d6-AA13-33B0AB46EEAA}";
    //    protected string m_fileName;
    //    protected IntPtr f_hDrop = IntPtr.Zero;
    //    #endregion

    //    #region IContextMenu
    //    // IContextMenu
    //    int IContextMenu.QueryContextMenu(uint hMenu, uint iMenu, int idCmdFirst, int idCmdLast, uint uFlags)
    //    {
    //        // Create the popup to insert
    //        var hmnuPopup = User32.CreatePopupMenu();

    //        var id = 1;
    //        if((uFlags & 0xf) == 0 || (uFlags & (uint)CMF.CMF_EXPLORE) != 0)
    //        {
    //            var nselected = Shell32.DragQueryFile(f_hDrop, 0xffffffff, null, 0);
    //            if(nselected == 1)
    //            {
    //                var sb = new StringBuilder(1024);
    //                Shell32.DragQueryFile(f_hDrop, 0, sb, sb.Capacity + 1);
    //                m_fileName = sb.ToString();

    //                // Populate the popup menu with file-specific items
    //                id = PopulateMenu(hmnuPopup, idCmdFirst + id);
    //            }

    //            // Add the popup to the context menu
    //            var mii = new MENUITEMINFO();
    //            mii.cbSize = 48;
    //            mii.fMask = (uint)MIIM.TYPE | (uint)MIIM.STATE | (uint)MIIM.SUBMENU;
    //            mii.hSubMenu = (int)hmnuPopup;
    //            mii.fType = (uint)User32.SystemMenu.MF.MF_STRING;
    //            mii.dwTypeData = "Actions";
    //            mii.fState = (uint)User32.SystemMenu.MF.MF_ENABLED;
    //            User32.InsertMenuItem(hMenu, (uint)iMenu, 1, ref mii);

    //            // Add a separator
    //            var sep = new MENUITEMINFO();
    //            sep.cbSize = 48;
    //            sep.fMask = (uint)MIIM.TYPE;
    //            sep.fType = (uint)User32.SystemMenu.MF.MF_SEPARATOR;
    //            User32.InsertMenuItem(hMenu, iMenu + 1, 1, ref sep);

    //        }
    //        return id;
    //    }

    //    void AddMenuItem(uint hMenu, string text, int id, uint position)
    //    {
    //        var mii = new MENUITEMINFO();
    //        mii.cbSize = 48;
    //        mii.fMask = (uint)MIIM.ID | (uint)MIIM.TYPE | (uint)MIIM.STATE;
    //        mii.wID = id;
    //        mii.fType = (uint)User32.SystemMenu.MF.MF_STRING;
    //        mii.dwTypeData = text;
    //        mii.fState = (uint)User32.SystemMenu.MF.MF_ENABLED;
    //        User32.InsertMenuItem(hMenu, position, 1, ref mii);
    //    }

    //    int PopulateMenu(IntPtr hMenu, int id)
    //    {
    //        // Grab some info about the file
    //        var done = ProcessBatchResults();

    //        if(done)
    //        {
    //            AddMenuItem(hMenu, "Reschedule", id, 0);
    //            AddMenuItem(hMenu, "Retry Now", ++id, 1);
    //            AddMenuItem(hMenu, "Cancel", ++id, 2);
    //        }
    //        else
    //        {
    //            // Uses 100-baed values to distinguish on the "done" status
    //            AddMenuItem(hMenu, "Commit", 100 + id, 0);
    //            AddMenuItem(hMenu, "Rollback", 100 + (++id), 1);
    //        }

    //        return id++;
    //    }

    //    bool ProcessBatchResults()
    //    {
    //        var fi = new FileInfo(m_fileName);
    //        return (fi.Length > 0);
    //    }


    //    void IContextMenu.GetCommandString(int idCmd, uint uFlags, int pwReserved, StringBuilder commandString, int cchMax)
    //    {
    //        switch(uFlags)
    //        {
    //            case (uint)GCS.VERB:
    //                commandString = new StringBuilder("...");
    //                break;
    //            case (uint)GCS.HELPTEXT:
    //                commandString = new StringBuilder("...");
    //                break;
    //        }
    //    }


    //    void IContextMenu.InvokeCommand(IntPtr pici)
    //    {
    //        try
    //        {
    //            var typINVOKECOMMANDINFO = typeof(INVOKECOMMANDINFO); // Type.GetType("ShellExt.INVOKECOMMANDINFO");
    //            var ici = (INVOKECOMMANDINFO)Marshal.PtrToStructure(pici, typINVOKECOMMANDINFO);
    //            switch(ici.verb - 1)
    //            {
    //                case 0:
    //                    RescheduleJob();
    //                    break;
    //                case 1:
    //                    RetryNowJob();
    //                    break;
    //                case 2:
    //                    CancelJob();
    //                    break;
    //                case 100:
    //                    CommitJob();
    //                    break;
    //                case 101:
    //                    RollbackJob();
    //                    break;
    //            }
    //        }
    //        catch(Exception)
    //        {
    //        }
    //    }
    //    #endregion

    //    #region IShellExtInit
    //    int IShellExtInit.Initialize(IntPtr pidlFolder, IntPtr lpdobj, uint hKeyProgID)
    //    {
    //        try
    //        {
    //            if(lpdobj != IntPtr.Zero)
    //            {
    //                // Get info about the directory
    //                var dataObject = (IDataObject)Marshal.GetObjectForIUnknown(lpdobj);
    //                var fmt = new FORMATETC
    //                              {
    //                                  cfFormat = (short)CLIPFORMAT.CF_HDROP,
    //                                  ptd = IntPtr.Zero,
    //                                  dwAspect = DVASPECT.DVASPECT_CONTENT,
    //                                  lindex = -1,
    //                                  tymed = TYMED.TYMED_HGLOBAL
    //                              };
    //                STGMEDIUM medium;
    //                dataObject.GetData(ref fmt, out medium);
    //                f_hDrop = medium.unionmember; // hGlobal;
    //            }
    //        }
    //        catch(Exception)
    //        {
    //        }
    //        return 0;
    //    }

    //    #endregion

    //    #region Private Members
    //    private void CancelJob()
    //    {
    //        MessageBox.Show("Gotta cancel the job", Path.GetFileName(m_fileName));
    //    }
    //    private void RescheduleJob()
    //    {
    //        MessageBox.Show("Gotta reschedule the job", Path.GetFileName(m_fileName));
    //    }
    //    private void RetryNowJob()
    //    {
    //        MessageBox.Show("Gotta retry the job NOW", Path.GetFileName(m_fileName));
    //    }
    //    private void CommitJob()
    //    {
    //        MessageBox.Show("Gotta commit the job", Path.GetFileName(m_fileName));
    //    }
    //    private void RollbackJob()
    //    {
    //        MessageBox.Show("Gotta rollback the job", Path.GetFileName(m_fileName));
    //    }
    //    #endregion

    //    #region Registration
    //    [ComRegisterFunction]
    //    public static void RegisterServer(String str1)
    //    {
    //        try
    //        {
    //            // For Winnt set me as an approved shellex
    //            var root = Registry.LocalMachine;
    //            var rk = root.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", true);
    //            Debug.Assert(rk != null, "rk != null");
    //            rk.SetValue(guid, "BatchResults shell extension");
    //            rk.Close();

    //            // Set "Folder\\shellex\\ContextMenuHandlers\\BatchResults" regkey to my guid
    //            root = Registry.ClassesRoot;
    //            rk = root.CreateSubKey("POPUPTEST\\shellex\\ContextMenuHandlers\\BatchResults");
    //            Debug.Assert(rk != null, "rk != null");
    //            rk.SetValue("", guid);
    //            rk.Close();
    //        }
    //        catch(Exception e)
    //        {
    //            Console.WriteLine(e);
    //        }
    //    }

    //    [ComUnregisterFunction]
    //    public static void UnregisterServer(String str1)
    //    {
    //        try
    //        {
    //            // Remove ShellExtenstions registration
    //            var root = Registry.LocalMachine;
    //            var rk = root.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", true);
    //            Debug.Assert(rk != null, "rk != null");
    //            rk.DeleteValue(guid);
    //            rk.Close();

    //            // Delete  regkey
    //            root = Registry.ClassesRoot;
    //            root.DeleteSubKey("POPUPTEST\\shellex\\ContextMenuHandlers\\BatchResults");
    //        }
    //        catch(Exception e)
    //        {
    //            Console.WriteLine(e);
    //        }
    //    }
    //    #endregion

    //}


    [StructLayout(LayoutKind.Sequential)]
    public struct MENUITEMINFO
    {
        public uint cbSize;
        public uint fMask;
        public uint fType;
        public uint fState;
        public uint wID;
        public IntPtr hSubMenu;
        public IntPtr hbmpChecked;
        public IntPtr hbmpUnchecked;
        public IntPtr dwItemData;
        public string dwTypeData;
        public uint cch;
        public IntPtr hbmpItem;

        // return the size of the structure
        public static uint sizeOf
        {
            get { return (uint)Marshal.SizeOf(typeof(MENUITEMINFO)); }
        }
    }

    [ComVisible(false)]
    public enum CLIPFORMAT
    {
        CF_TEXT = 1,
        CF_BITMAP = 2,
        CF_METAFILEPICT = 3,
        CF_SYLK = 4,
        CF_DIF = 5,
        CF_TIFF = 6,
        CF_OEMTEXT = 7,
        CF_DIB = 8,
        CF_PALETTE = 9,
        CF_PENDATA = 10,
        CF_RIFF = 11,
        CF_WAVE = 12,
        CF_UNICODETEXT = 13,
        CF_ENHMETAFILE = 14,
        CF_HDROP = 15,
        CF_LOCALE = 16,
        CF_MAX = 17,
        CF_OWNERDISPLAY = 0x80,
        CF_DSPTEXT = 0x81,
        CF_DSPBITMAP = 0x82,
        CF_DSPMETAFILEPICT = 0x83,
        CF_DSPENHMETAFILE = 0x8E,
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct INVOKECOMMANDINFO
    {
        public static INVOKECOMMANDINFO Default { get { return new INVOKECOMMANDINFO { cbSize = Marshal.SizeOf(typeof(INVOKECOMMANDINFO)) }; } }

        public int cbSize;    // sizeof(INVOKECOMMANDINFO)
        public int fMask;     // any combination of CMIC_MASK_*
        public IntPtr hwnd;      // might be NULL (indicating no owner window)
        public string lpVerb;    // either a string or MAKEINTRESOURCE(idOffset)
        public string lpParameters;  // might be NULL (indicating no parameter)
        public string lpDirectory;   // might be NULL (indicating no specific directory)
        public int nShow;     // one of SW_ values for ShowWindow() API
        public int dwHotKey;
        public IntPtr hIcon;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct INVOKECOMMANDINFOEX
    {
        public static INVOKECOMMANDINFOEX Default { get { return new INVOKECOMMANDINFOEX { cbSize = Marshal.SizeOf(typeof(INVOKECOMMANDINFOEX)) }; } }

        public int cbSize;        // Marshal.SizeOf(CMINVOKECOMMANDINFO)
        public int fMask;         // any combination of CMIC_MASK_*
        public IntPtr hwnd;          // might be NULL (indicating no owner window)
        public string lpVerb;        // either a string or MAKEINTRESOURCE(idOffset)
        public string lpParameters;      // might be NULL (indicating no parameter)
        public string lpDirectory;       // might be NULL (indicating no specific directory)
        public int nShow;         // one of SW_ values for ShowWindow() API
        public int dwHotKey;        // Optional hot key to assign to any application activated by the command. If the fMask member does not specify CMIC_MASK_HOTKEY, this member is ignored. 
        public IntPtr hIcon;            // Icon to use for any application activated by the command. If the fMask member does not specify CMIC_MASK_ICON, this member is ignored. 

        public string lpTitle;        // ASCII title.

        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpVerbW;                // Unicode verb, for those commands that can use it.

        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpParametersW;        // Unicode parameters, for those commands that can use it. 

        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpDirectoryW;        // Unicode directory, for those commands that can use it.

        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpTitleW;            // Unicode title.

        public POINT ptInvoke;                // POINT where the command is invoked. This member is not valid prior to Microsoft Internet Explorer 4.0.
    }
}